//
// Created by zhouheyu on 17-12-2.
//

#ifndef AD_CLUSTER2_AD_C2_H
#define AD_CLUSTER2_AD_C2_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

//关于对其操作的宏定义
#define SEC_PRE_PAGE 4
#define PAGE_PRE_BLK 64
#define SEC_PRE_BLK  256
#define CACHE_READ_DELAY 0.005
#define CACHE_WRITE_DELAY 0.005
#define FLASH_READ_DELAY 0.05
#define FLASH_WRITE_DELAY 0.25

//定义LPN节点
typedef struct Node
{
    int LPN;
    struct Node *Pre;
    struct Node *Next;
    int isD;
}Node ,*pNode;

//定义BlkTale的节点
typedef struct BNode
{
    int BlkNum;
    struct BNode *Pre;
    struct BNode *Next;
    int CleanNum;
    int DirtyNum;
    int Size;
    int CleanList[PAGE_PRE_BLK];
    int DirtyList[PAGE_PRE_BLK];
}BNode,*pBNode;

int buf_size;
//依次表示脏页和干净页的队列的头部
pNode CHead;
pNode DHead;
//定义对应的块索引的头节点
pBNode BHead;
//表示目标队列的长度
int Tau;
double MinTauRatio;
double MaxTauRatio;
//周期更新对应的Tau的中间变量
int CDHit_CWH;
int CDHit_CRH;
int CDHit_DRH;
int CDHit_DWH;
//周期更新
int T_count;
int UpdateTauCycle;
//wAmp写入放大系数
double wAmp;
int cycle_physical_write;
int cycle_physical_read;
double cycle_flash_write_delay;
double cycle_flash_read_delay;
//表示当前的长度
int CLRU_Length;
int DLRU_Length;
//当前的块索引长度
int BlkTable_Size;
//相关的统计变量
int buffer_hit;
int buffer_miss_cnt;
int buffer_cnt;
int buffer_read_hit;
int buffer_read_miss;
int buffer_write_hit;
int buffer_write_miss;
int physical_read;
int physical_write;
int cache_write_num;
int cache_read_num;
//表示当前的冷热阈值
int Threshold;

//DelVictim-list need simple-list
typedef struct VNode{
	int LPN;
	struct VNode *Next;
	struct VNode *Pre;
	struct Node *pIndex;
}VNode,*pVNode;

pNode CreateList();
void InitVariable();
void resetCacheStat();
//判断链表是否为空
int IsEmptyList(pNode pHead);
//输出打印链表
void PrintList(pNode pHead);
//计算链表长度
int GetListLength(pNode pHead);
//删除整个链表，释放内存
void FreeList(pNode pHead);
//释放节点pBNode的链表
void FreeBList(pBNode pHead);
//向链表中删除节点
int DeleteEleList(pNode pHead,int pos);
//从链表中找到特定的LPN值，并返回节点的指针位置,如果不存在返回NULL
pNode FindLPNinList(pNode pHead,int LPN);
//从链表中插入节点,这里之后有读写操作的operation
int InsertEleList(pNode pHead,int pos,int LPN,int operation);
//计算缓冲区的读写延迟
double ComputeCacheDelay();
//缓冲区的算法函数
double CacheManage(int secno,int scount,int operation );
//输出对应的统计结果
void PrintResultStat();

double AddNewToBuffer(pNode CHead,pNode DHead,int LPN,int operation);
int myMax(int a,int b);
int myMin(int a,int b);
int UpdateTau();
//找到块索引链表中的位置
pBNode FindBlkTable(pBNode Head,int BlkNum);
//没有找到对应的数据则返回-1
int search_table(int *arr,int size,int val);
int find_free_pos( int *arr, int size);
//命中CLRU的操作,存在命中的请求类型
int HitCLRU(pNode CHead,pNode DHead,pNode pHit,int operation);
//命中DLRU的操作
int HitDLRU(pNode DHead,pNode pHit,int operation);
//删除CLRU中的数据，返回的是删除的LPN号
int DelCLRU(pNode CHead);
//非聚簇删除DLRU的数据，设计回写操作，有时延
double DelOneDLRU(pNode DHead);

//find value in list pos-index,-1(no exist)
//pos--->0---Size-1
int FindValueInList(pNode Head,int Val);
//calculate nonegative value num in arr
int calculate_nonegative_arr(int *arr,int size);


#endif //AD_CLUSTER2_AD_C2_H
